#pragma once

#ifdef PUNCH_MSGPACK
#include <msgpack.hpp>
#endif

#include "../BaseOrder.h"

namespace mdtx::punch::tradesim
{
    template <typename TT, typename TI, typename TQ>
    struct Quote
    {
        using time_type = TT;
        using id_type = TI;
        using quant_type = TQ;

        TQ price, quant;
        TI ins_id, cli_id, seq_id;

#ifdef PUNCH_MSGPACK
        MSGPACK_DEFINE_ARRAY(price, quant, ins_id, cli_id, seq_id);

        Quote()
        {
        }
#endif

        Quote(TQ price, TQ quant)
            : price{price}, quant{quant},
              ins_id{}, cli_id{}, seq_id{}
        {
        }

        Quote(TQ price, TQ quant, TI ins_id, TI cli_id)
            : price{price}, quant{quant},
              ins_id{ins_id}, cli_id{cli_id}, seq_id{}
        {
        }

        void set_ins(TI ins_id)
        {
            this->ins_id = ins_id;
        }

        void set_cli(TI cli_id)
        {
            this->cli_id = cli_id;
        }

        void set_seq(TI seq_id)
        {
            this->seq_id = seq_id;
        }

        struct BidComparator
        {
            bool operator()(const Quote &lhs, const Quote &rhs) const
            {
                return (lhs.price > rhs.price) || (lhs.price == rhs.price && lhs.seq_id < rhs.seq_id);
            }

            static constexpr bool better_price(TQ lhs, TQ rhs)
            {
                return lhs > rhs;
            }
        };

        struct AskComparator
        {
            bool operator()(const Quote &lhs, const Quote &rhs) const
            {
                return (lhs.price < rhs.price) || (lhs.price == rhs.price && lhs.seq_id < rhs.seq_id);
            }

            static constexpr bool better_price(TQ lhs, TQ rhs)
            {
                return lhs < rhs;
            }
        };
    };

    template <typename QT>
    using Order = BaseOrder<QT>;
}
